package sweet.helper

import java.util.Date
import java.util.Calendar
import java.text.SimpleDateFormat

/**
 * The companion of JDate class. 
 */
object JDate{
 // ==================== 
 // Note that java.text.SimpleDateFormat is not ThreadSafe, so it's important to use "def" instead of val 
 // when return a new instance object whem adding more methods to this class.
 // ====================
 
  /** yyyy-MM-dd */
  val DATE_FMT = "yyyy-MM-dd"
  /** HH:mm:ss */
  val TIME_FMT = "HH:mm:ss"
  /** yyyy-MM-dd HH:mm:ss */
  val DATETIME_FMT = "yyyy-MM-dd HH:mm:ss"
  
  /** Create new DateFormat instance using DATE_FMT. */
  def dateDf = new SimpleDateFormat(DATE_FMT)
  /** Create new DateFormat instance using TIME_FMT. */
  def timeDf = new SimpleDateFormat(TIME_FMT)
  /** Create new DateFormat instance using DATETIME_FMT. */
  def datetimeDf = new SimpleDateFormat(DATETIME_FMT)
  
  /** Call #now */
  def apply() = now  
  /** Call #mkdate */
  def apply(dt: String) = mkdate(dt)
  /** Call #mkFrom */
  def apply(dt: String, fmt: String) = mkdateFrom(dt, fmt)
  /** Call #mkdate */
  def apply(year: Int, month: Int, date: Int) = mkdate(year, month, date)
  /** Call #mkdatetime */
  def apply(year: Int, month: Int, date: Int, hour: Int, min: Int, sec: Int) = 
    mkdatetime(year, month, date, hour, min, sec)
    
  /** Create new timestamp/date instance of JDate that wraps java.util.Date */
  def now = new JDate(new Date) //today's datetime
  /** Same as now.dateDf */
  def today = now.datePart //today's date part only
  /** Same as now.timePart */
  def time = now.timePart //today's time part only.
  /** Create a date with DATE_FMT parts ONLY. */
  def mkdate(dt: String) = new JDate(dateDf.parse(dt))
  /** Create a date with TIME_FMT parts ONLY. */
  def mktime(dt: String) = new JDate(timeDf.parse(dt))
  /** Create a date with DATETIME_FMT parts ONLY. */
  def mkdatetime(dt: String) = new JDate(datetimeDf.parse(dt))
  
  /** Create a date using given numberical parameters */
  def mkdate(year: Int, month: Int, date: Int) = new JDate(dateDf.parse(year+"-"+month+"-"+date))
  /** Create a date using given numberical parameters */
  def mktime(hour: Int, min: Int, sec: Int) = new JDate(timeDf.parse(hour+":"+min+":"+sec))
  /** Create a date using given numberical parameters */
  def mkdatetime(year: Int, month: Int, date: Int, hour: Int, min: Int, sec: Int) = 
    new JDate(datetimeDf.parse(year+"-"+month+"-"+date+" "+hour+":"+min+":"+sec))
    
  /** Create a date using java.text.SimpleDateFormat format string. */
  def mkdateFrom(dt: String, fmt: String) = new JDate(new SimpleDateFormat(fmt).parse(dt))
  
  /** implicit converter from Date to JDate */
  implicit def date2jdate(dt: Date) = new JDate(dt)
}

/** A wrapper to java.util.Date that provide convinient methods to handle date and time. */
class JDate(val date: Date){
  import JDate._
  /** return millis seconds of instance of given date. */
  def millis = date.getTime
  /** return seconds of instance of given date. */
  def secs = (date.getTime / 1000).toInt
  /** return mins of instance of given date. */
  def mins = (date.getTime / 1000*60).toInt
  /** return hours of instance of given date. */
  def hours = (date.getTime / 1000*60*60).toInt
  /** return a formated date string of instance of given date. (See java.text.SimpleDateFormat) */
  def format(fmt: String) = new SimpleDateFormat(fmt).format(date)
  
  /** return date portion of a date object */
  def datePart = { val df = dateDf; df.parse(df.format(date)) }
  /** return time portion of a date object */
  def timePart = { val df = timeDf; df.parse(df.format(date)) }
  
  /** return DATE_FMT string */
  def dateString = { dateDf.format(date) }
  /** return TIME_FMT string */
  def timeString = { timeDf.format(date) }
  /** return DATETIME_FMT string */
  def datetimeString = { datetimeDf.format(date) }
}
